//1  构造函数
function NewFun1(value){
    this.key1=value,
    this.key2='嘻嘻嘻'

    this.fun1=function(){
        console.log('我是fun1')
    }
}

//实例
const obj1=new NewFun1('哈哈哈')

console.log('obj1',obj1)
obj1.fun1()

//============================================

//2  构造函数(含prototype原型),(构造函数都有prototype指向原型, new出的实例都有__proto__指向原型, 原型中有constructor指回构造函数)
function NewFun2(){
    this.key1='嘻嘻嘻'
}

NewFun2.prototype.proFun=function(){
    console.log('我是proFun')
}

const obj2=new NewFun2()
console.log('obj2',obj2)
obj2.proFun()

//===============================================

//3  继承
//父
function Father(value){
    this.key1=value
    this.key2='嘻嘻嘻'
}
Father.prototype.fatherfun=function(){
    console.log('我是父辈的函数')
}

//子
function Son(value){
    //继承父辈属性
    Father.call(this,value)
    //子辈自已的属性
    this.key3='嘎嘎嘎'
}
//继承公共方法
// Son.prototype=new Father//缺点:会将属性一同赋值给子的prototype
// Object.assign(Son.prototype,Father.prototype)//缺点:assign的赋值不是全能拷贝的(assign是拷贝值,而不拷贝它背后的赋值方法和取值方法)
Object.defineProperties(Son.prototype,Object.getOwnPropertyDescriptors(Father.prototype))
//将子prototype中的constructor指回构造函数
Son.prototype.constructor=Son

//调用
const sonObj=new Son('哈哈哈')
console.log('sonObj',sonObj)
sonObj.fatherfun()